package main

import (
	"context"
	"fmt"
	"log"
	"net/http"
	"os"
	"os/signal"
	"syscall"
	"time"

	"github.com/cloudflare/tableflip"
)

func main() {
	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		time.Sleep(3 * time.Second)
		fmt.Fprintf(w, "http Welcome\n")
	})

	srv := &http.Server{
		Handler:      http.DefaultServeMux,
		ReadTimeout:  30 * time.Second,
		WriteTimeout: 30 * time.Second,
	}

	pidfile := fmt.Sprintf("tableflip.%d", os.Getpid())
	upg, err := tableflip.New(tableflip.Options{PIDFile: pidfile})
	if err != nil {
		panic(err)
	}
	defer upg.Stop()
	defer os.Remove(pidfile)

	go func() {
		sig := make(chan os.Signal, 1)
		signal.Notify(sig, syscall.SIGHUP, syscall.SIGINT, syscall.SIGTERM)
		for s := range sig {
			switch s {
			case syscall.SIGHUP:
				err := upg.Upgrade()
				if err != nil {
					log.Println("Upgrade Failed:", err)
				} else {
					log.Println("Upgrade Success")
				}
			default:
				upg.Stop()
			}
		}
	}()

	ln, err := upg.Listen("tcp", ":19880")
	if err != nil {
		panic(err)
	}

	go func() {
		err := srv.Serve(ln)
		if err != http.ErrServerClosed {
			log.Println("HTTP server:", err)
		}
	}()

	if err := upg.Ready(); err != nil {
		panic(err)
	}

	log.Println("Ready")

	<-upg.Exit()

	srv.Shutdown(context.Background())
	log.Println("Shutdown Success")
}
